package com.hhit.zhgd.controller

import cn.dev33.satoken.stp.StpUtil
import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.hhit.zhgd.component.AlertFileProperties
import com.hhit.zhgd.component.WeatherApiProperties
import com.hhit.zhgd.domain.dto.AdminDTO
import com.hhit.zhgd.domain.entity.Admin
import com.hhit.zhgd.domain.response.BaseResp
import com.hhit.zhgd.service.AdminService
import com.hhit.zhgd.service.RoleService
import com.hhit.zhgd.utils.getClientIp
import com.hhit.zhgd.utils.getRandomString
import com.hhit.zhgd.utils.menuToTree
import com.hhit.zhgd.utils.toIntArr
import jakarta.annotation.Resource
import jakarta.servlet.http.HttpServletRequest
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.util.DigestUtils
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import java.util.*
import java.util.regex.Pattern
import javax.validation.constraints.Min
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

@Validated
@RestController
class AdminController {
    private val log= LoggerFactory.getLogger(AdminController::class.java)

    @Autowired
    private val adminService: AdminService? = null

    @Autowired
    private val roleService: RoleService? = null
    @PostMapping("/login")
    fun login(request: HttpServletRequest, @RequestBody params: HashMap<String, Any?>): BaseResp<*> {
        params["ip"] = request.getClientIp()
        val res: HashMap<String, *> = adminService?.checkLogin(params)!!

        if (res["status"] == false) {
            return BaseResp.fail(res["message"].toString())
        }
        val data: JSONObject = JSONObject.toJSON(res["data"]) as JSONObject

        val perms: MutableList<String> = ArrayList()
        val menus: MutableList<HashMap<String, Any?>>? =
            adminService.getPermissionList(StpUtil.getLoginIdAsInt())?.toMutableList()
        menus?.let {
            val iterator: MutableIterator<HashMap<String, *>> = menus.iterator()
            while (iterator.hasNext()) {
                val menu = iterator.next()
                if (menu["perms"] != null && menu["perms"].toString().isNotEmpty() && menu["type"] == "F") {
                    perms.add(menu["perms"].toString())
                    iterator.remove()
                }
                menu.remove("sort")
                menu.remove("status")
                menu.remove("perms")
                menu.remove("type")
            }
            val tree: List<Any> = menuToTree(menus, 0)
            data.put("menu", tree)
            data.put("perms", perms)
        }


        return BaseResp.success(data)
    }


    @GetMapping("/logout")
    fun logout(): BaseResp<Any?> {
        StpUtil.logout()
        return BaseResp.success()
    }


    @GetMapping("/admins")
    fun getAdminList(
        username: String?,
        role: Int?,
        status: Int?,
        @RequestParam(name = "page", defaultValue = "1") page: Int,
        @RequestParam(name = "size", defaultValue = "10") size: Int
    ): BaseResp<Page<HashMap<String, *>>?> {
        val params = HashMap<String, Any?>()
        params["username"] = username
        params["role"] = role
        params["status"] = status

        val pages = Page<HashMap<String, Any?>>(page.toLong(), size.toLong())
        val list = adminService?.getList(pages, params)

        return BaseResp.success(list)
    }

    @GetMapping("/admins/{id}")
    fun getAdminInfo(
        @PathVariable("id") @Min(
            value = 1,
            message = "id必须大于0"
        ) adminId: Int
    ): BaseResp<HashMap<String, Any?>?> {
        val data = HashMap<String, Any?>()
        val info = adminService?.getById(adminId)
        if (info != null) {
            data["id"] = info.id
            data["username"] = info.username
            data["status"] = info.status
            data["role"] = info.role?.toIntArr()
        }

        return BaseResp.success(data)
    }


    @PostMapping("/admin")
    fun addAdmin(@Validated(AdminDTO.Save::class) form: AdminDTO): BaseResp<Any?> {
        val res = roleService?.checkRole(form.role_ids!!)
        if (res == false) {
            return BaseResp.fail("角色不存在")
        }

        val params = HashMap<String, Any?>()
        params["username"] = form.username
        val info = adminService?.getInfo(params)
        if (info != null) {
            return BaseResp.fail("用户名已存在")
        }

        val safe = getRandomString(4);
        val admin = Admin(
            id = form.id,
            username = form.username,
            safe = safe,
            password = DigestUtils.md5DigestAsHex((form.password + safe).toByteArray()),
            role = "[${form.role_ids}]",
            createTime = Date(),
            updateTime = Date()
        )
        adminService?.save(admin)
        return BaseResp.success()
    }


    @PutMapping("/admin")
    fun editAdmin(@Validated(AdminDTO.Update::class) form: AdminDTO): BaseResp<Any?> {
        val params = HashMap<String, Any?>()
        params["id"] = form.id
        val info = adminService?.getInfo(params)
        if (info == null || info["root"] == 1) {
            return BaseResp.fail("用户不存在")
        }

        val res = roleService?.checkRole(form.role_ids!!)
        if (false == res) {
            return BaseResp.fail("角色不存在")
        }

        if ((form.password?.length ?: 0) > 0) {
            val pattern = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d\\W]{6,18}$"
            if (!Pattern.matches(pattern, form.password)) {
                return BaseResp.fail("密码必须包含字母和数字，且在6-18位之间")
            }
            val safe = getRandomString(4)
            val admin = Admin(
                id = info["id"].toString().toLong(),
                username = null,
                safe = safe,
                password = DigestUtils.md5DigestAsHex((form.password + safe).toByteArray()),
                role = "[${form.role_ids}]",
                updateTime = Date()
            )
            adminService?.updateById(admin)

            if (0 == form.status) {
                StpUtil.logout(form.id)
            }
            return BaseResp.success()
        } else {
            return BaseResp.fail("密码不能为空")
        }
    }

    @DeleteMapping("/admin/{id}")
    fun delAdmin(@PathVariable("id") @Min(value = 1, message = "id必须大于0") adminId: Int): BaseResp<Any?> {
        if (StpUtil.getLoginIdAsInt() == adminId) {
            return BaseResp.fail("不能删除当前登录账户")
        } else {
            val params = HashMap<String, Any?>()
            params["id"] = adminId
            val info = adminService?.getInfo(params)
            if (info==null || info["root"].toString() == "1") {
                return BaseResp.fail("用户不存在")
            } else {
                val removeById = adminService?.removeById(adminId)
                if (true == removeById) {
                    return BaseResp.success()
                } else {
                    return BaseResp.fail("删除失败")
                }
            }
        }
    }
}



























